package cn.bugstack.chatgpt.data.domain.openai.service.rule.factory;

import cn.bugstack.chatgpt.data.domain.openai.annotation.LogicStrategy;
import cn.bugstack.chatgpt.data.domain.openai.service.rule.ILogicFilter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 *  规则工厂，策略逻辑注册中心，根据业务枚举获取对应的过滤逻辑处理器
 * “注解标记 → 枚举策略 → 注入到工厂 → 运行时按需调用”的策略分发机制
 */
@Service
public class DefaultLogicFactory {

    public Map<String, ILogicFilter> logicFilterMap = new ConcurrentHashMap<>();

    /**
     * 工厂核心初始化逻辑
     * 1.自动注入Spring中所有实现了ILogicFilter接口的Bean
     * 2.通过反射获取注解用 Spring 的 AnnotationUtils.findAnnotation() 获取每个类上的 @LogicStrategy 注解。
     * 3.把枚举的 code() 做 key，类实例作为 value，存进 map
     *
     * 最终形成一个这样的 map：
     * key（策略类型code）	｜    value（策略实现类实例）
     * "ACCESS_LIMIT"	    ｜    AccessLimitLogic 实例
     * "SENSITIVE_WORD"	    ｜    SensitiveWordLogic 实例
     *
     * 也就是说，后续只需要通过
     * ILogicFilter logic = logicFactory.openLogicFilter().get("ACCESS_LIMIT");
     * logic.filter(chatProcess);
     * 这样就能动态、按需地执行对应策略的处理逻辑！
     */

    public DefaultLogicFactory(List<ILogicFilter> logicFilters) {
        logicFilters.forEach(logic -> {
            LogicStrategy strategy = AnnotationUtils.findAnnotation(logic.getClass(), LogicStrategy.class);
            if (null != strategy) {
                logicFilterMap.put(strategy.logicMode().getCode(), logic);
            }
        });
    }

    public Map<String, ILogicFilter> openLogicFilter() {
        return logicFilterMap;
    }


    /**
     * 规则逻辑枚举
     */
    public enum LogicModel {

        ACCESS_LIMIT("ACCESS_LIMIT", "访问次数过滤"),
        SENSITIVE_WORD("SENSITIVE_WORD", "敏感词过滤"),
        ;

        private String code;
        private String info;

        LogicModel(String code, String info) {
            this.code = code;
            this.info = info;
        }

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }

        public String getInfo() {
            return info;
        }

        public void setInfo(String info) {
            this.info = info;
        }
    }

}
